'''
实验名称：pyCar红外遥控+MQTT远程控制 (SSL版本)
版本：v2.2 - 增加自动重连机制
日期：2025-07-20
作者：hal3000
增加功能：SSL MQTT支持 + 自动重连机制
'''

from car import CAR
import time
import network
from simple import MQTTClient  # 使用支持SSL的版本
from machine import Pin
import _thread
import gc  # 垃圾回收

# 导入配置文件
try:
    from config import *
    print("✅ 已加载配置文件")
except ImportError:
    print("❌ 未找到配置文件 config.py")
    print("💡 请复制 config_template.py 为 config.py 并填入你的配置信息")
    print("📖 详细说明请查看 README.md")
    raise ImportError("缺少配置文件")

# 验证配置
if WIFI_SSID == 'your_wifi_name' or WIFI_PASSWORD == 'your_wifi_password':
    print("⚠️  警告: 请修改 config.py 中的WiFi配置")
    raise ValueError("WiFi配置未修改")

if BROKER_ADDRESS == "your_mqtt_broker.com" or USERNAME == "your_mqtt_username":
    print("⚠️  警告: 请修改 config.py 中的MQTT配置")
    raise ValueError("MQTT配置未修改")

Car = CAR()
mqtt_command = None
mqtt_connected = False
mqtt_client = None
wifi_led = Pin(2, Pin.OUT)

def wifi_connect():
    """连接WiFi"""
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    start_time = time.time()
    
    print("连接WiFi:", WIFI_SSID)
    
    if not wlan.isconnected():
        wlan.connect(WIFI_SSID, WIFI_PASSWORD)
        while not wlan.isconnected():
            wifi_led.value(1)
            time.sleep_ms(300)
            wifi_led.value(0)
            time.sleep_ms(300)
            print(".", end="")
            if time.time() - start_time > 15:
                print("超时!")
                return False
    
    if wlan.isconnected():
        wifi_led.value(1)
        network_info = wlan.ifconfig()
        print("WiFi OK, IP:", network_info[0])
        return True
    return False

def wifi_check_and_reconnect():
    """检查WiFi连接状态并在需要时重连"""
    wlan = network.WLAN(network.STA_IF)
    if not wlan.isconnected():
        print("WiFi断开，尝试重连...")
        wifi_led.value(0)
        return wifi_connect()
    return True

def mqtt_callback(topic, msg):
    """MQTT回调函数"""
    global mqtt_command
    try:
        message = msg.decode('utf-8')
        print("MQTT收到:", message)
        mqtt_command = message
    except Exception as e:
        print("MQTT回调错误:", e)

def init_mqtt():
    """初始化MQTT连接 - SSL版本"""
    global mqtt_connected, mqtt_client
    try:
        print("MQTT连接:", BROKER_ADDRESS)
        
        # 创建SSL客户端
        client = MQTTClient(
            client_id=CLIENT_ID,
            server=BROKER_ADDRESS,
            port=PORT,
            user=USERNAME,
            password=PASSWORD,
            ssl=True  # 启用SSL
        )
        client.set_callback(mqtt_callback)
        
        print("建立SSL连接...")
        client.connect()
        print("MQTT SSL OK")
        
        print("订阅:", TOPIC)
        client.subscribe(TOPIC)
        print("订阅OK")
        
        mqtt_connected = True
        mqtt_client = client
        return client
    except Exception as e:
        print("MQTT失败:", e)
        mqtt_connected = False
        mqtt_client = None
        return None

def mqtt_reconnect():
    """MQTT重连函数"""
    global mqtt_connected, mqtt_client
    print("尝试MQTT重连...")
    mqtt_connected = False
    mqtt_client = None
    
    # 等待一下再重连
    time.sleep(2)
    
    # 先确保WiFi连接正常
    if not wifi_check_and_reconnect():
        print("WiFi重连失败，MQTT重连终止")
        return False
    
    # 尝试重连MQTT
    new_client = init_mqtt()
    if new_client:
        print("MQTT重连成功")
        return True
    else:
        print("MQTT重连失败")
        return False

def mqtt_keep_alive(client):
    """MQTT保活线程 - 增加重连机制"""
    global mqtt_connected, mqtt_client
    print("MQTT线程启动")
    
    reconnect_attempts = 0
    max_reconnect_attempts = 5
    
    while True:
        try:
            if mqtt_connected and mqtt_client:
                mqtt_client.check_msg()
                time.sleep(0.1)
                reconnect_attempts = 0  # 重置重连计数
            else:
                # MQTT未连接，尝试重连
                if reconnect_attempts < max_reconnect_attempts:
                    print("MQTT重连尝试 {}/{}".format(reconnect_attempts + 1, max_reconnect_attempts))
                    if mqtt_reconnect():
                        reconnect_attempts = 0
                    else:
                        reconnect_attempts += 1
                        time.sleep(5)  # 重连失败等待5秒
                else:
                    print("MQTT重连次数达到上限，等待30秒后重置...")
                    time.sleep(30)
                    reconnect_attempts = 0
                    
        except Exception as e:
            print("MQTT线程错误:", e)
            mqtt_connected = False
            mqtt_client = None
            time.sleep(5)

def process_mqtt_command(command):
    """处理MQTT指令"""
    if command:
        command = command.lower().strip()
        print("执行:", command)
        
        if command in ["forward", "w", "1"]:
            Car.forward_distance(20)
            print("前进20CM完成")
        elif command in ["backward", "s", "2"]:
            Car.backward()
            time.sleep(1)
            Car.stop()
            print("后退完成")
        elif command in ["left", "a", "3"]:
            Car.turn_left()
            time.sleep(0.5)
            Car.stop()
            print("左转完成")
        elif command in ["right", "d", "4"]:
            Car.turn_right()
            time.sleep(0.5)
            Car.stop()
            print("右转完成")
        elif command in ["stop", "x", "0"]:
            Car.stop()
            print("停止")
        elif command in ["calibrate", "cal"]:
            Car.calibrate_speed()
            print("校准完成")
        elif command.upper() == "L":
            Car.light_toggle()
            print("所有灯切换")
        elif command.upper() == "TL":
            Car.tail_lights_toggle()
            print("尾灯切换")
        elif command.upper() == "B":
            Car.light_blink(5)
            print("所有灯闪烁完成")
        elif command.upper() == "RR":
            Car.rotate_clockwise_full()
            print("顺时针旋转完成")
        elif command.upper() == "RL":
            Car.rotate_counterclockwise_full()
            print("逆时针旋转完成")
        else:
            print("未知指令:", command)

# 主程序
print("pyCar MQTT控制系统 v2.2 - 自动重连版")
gc.collect()  # 初始垃圾回收

# 1. 连接WiFi
if wifi_connect():
    print("WiFi成功")
    
    # 2. 连接MQTT (SSL)
    print("初始化MQTT...")
    mqtt_client = init_mqtt()
    
    if mqtt_client:
        print("MQTT成功")
        
        # 3. 启动MQTT监听线程
        print("启动线程...")
        _thread.start_new_thread(mqtt_keep_alive, (mqtt_client,))
        print("线程OK")
        
        print("控制系统就绪:")
        print("红外遥控器+MQTT控制")
        print("话题:", TOPIC)
        print("指令:")
        print("forward/w/1-前进20CM")
        print("backward/s/2-后退1秒") 
        print("left/a/3-左转, right/d/4-右转")
        print("stop/x/0-停止, cal-校准")
        print("L-所有灯切换, TL-尾灯切换")
        print("B-所有灯闪烁5次")
        print("RR-顺时针转, RL-逆时针转")
        print("已启用自动重连机制")
        print("系统就绪")
        
    else:
        print("MQTT失败，将在后台尝试重连")
else:
    print("WiFi失败")

# 主控制循环
loop_count = 0
last_wifi_check = 0

while True:
    try:
        # 红外控制
        ir_value = Car.getIR()
        if ir_value is not None and ir_value != "REPEAT":
            print("IR:", ir_value)
            if ir_value == 24:
                Car.forward_distance(20)
                print("前进20CM")
            elif ir_value == 82:
                Car.backward()
                time.sleep(1)
                Car.stop()
                print("后退")
            elif ir_value == 8:
                Car.turn_left()
                time.sleep(0.5)
                Car.stop()
                print("左转")
            elif ir_value == 90:
                Car.turn_right()
                time.sleep(0.5)
                Car.stop()
                print("右转")
            elif ir_value == 22:
                Car.light_toggle()
                print("所有灯切换")
            elif ir_value == 7:
                Car.tail_lights_toggle()
                print("尾灯切换")
            elif ir_value == 25:
                Car.light_blink(5)
                print("所有灯闪烁")
            elif ir_value == 13:
                Car.rotate_clockwise_full()
                print("顺时针转")
            elif ir_value == 12:
                Car.rotate_counterclockwise_full()
                print("逆时针转")
            else:
                Car.stop()
                print("停止")
        
        # MQTT控制
        if mqtt_command:
            process_mqtt_command(mqtt_command)
            mqtt_command = None
        
        # WiFi状态检查和重连 (每30秒检查一次)
        current_time = time.time()
        if current_time - last_wifi_check > 30:
            if not wifi_check_and_reconnect():
                print("WiFi重连失败")
            last_wifi_check = current_time
        
        # 状态检查和内存管理
        loop_count += 1
        if loop_count % 200 == 0:  # 减少检查频率节省资源
            wifi_status = network.WLAN(network.STA_IF).isconnected()
            print("状态 - WiFi:", "OK" if wifi_status else "NO", "MQTT:", "OK" if mqtt_connected else "NO")
            gc.collect()  # 垃圾回收
            
            # 每1000次循环显示内存信息
            if loop_count % 1000 == 0:
                try:
                    import micropython
                    micropython.mem_info()
                except:
                    pass
                    
    except Exception as e:
        print("主循环错误:", e)
        time.sleep(1)  # 发生异常时等待1秒
    
    time.sleep(0.1) 